package cn.melonlib.cores.aop.comp.inject;

import cn.hutool.core.bean.BeanUtil;
import cn.melonlib.cores.commons.comp.utils.AdvancedStringUtils;
import cn.melonlib.cores.commons.model.entity.TenantEntity;
import cn.melonlib.cores.identification.comp.messenger.IdentificationMessenger;
import cn.melonlib.cores.identification.model.entity.Organization;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.hibernate.service.spi.ServiceException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;

@Component
public class InjectTenantInterceptor extends ApplicationObjectSupport implements MethodInterceptor {


    @Resource
    private ObjectMapper jsonMapper;

    @Nullable
    @Override
    public Object invoke(@NotNull MethodInvocation methodInvocation) throws Throwable {
        IdentificationMessenger identificationMessenger = this.getApplicationContext().getBean(IdentificationMessenger.class);
        Arrays.stream(methodInvocation.getArguments()).forEach(arg -> {
            try {
                Organization organization = identificationMessenger.getOrganization();
                Serializable id = BeanUtil.getProperty(organization, "id");
                String code = AdvancedStringUtils.defaultIfBlank(BeanUtil.getProperty(organization, "code")
                        ,()->BeanUtil.getProperty(organization, "domain"));
                String name = organization.getName();
                if (arg instanceof TenantEntity) {
//                try {
                    ((TenantEntity) arg).setTenantId(String.valueOf(id));
                    ((TenantEntity) arg).setTenantCode(code);
                    ((TenantEntity) arg).setTenantName(name);
//                    ((TenantEntity) arg).setTenant(jsonMapper.writeValueAsString(identificationMessenger.getOrganization()));
//                } catch (JsonProcessingException e) {
//                    logger.error(e.getMessage(),e);
//                }
                } else if (arg instanceof Collection) {
                    ((Collection<?>) arg).stream().forEach(argItem -> {
                        if (argItem instanceof TenantEntity) {
//                        try {
                            ((TenantEntity) argItem).setTenantId(String.valueOf(id));
                            ((TenantEntity) argItem).setTenantCode(code);
                            ((TenantEntity) argItem).setTenantName(name);
//                            ((TenantEntity) argItem).setTenant(jsonMapper.writeValueAsString(identificationMessenger.getOrganization()));
//                        } catch (JsonProcessingException e) {
//                            logger.error(e.getMessage(), e);
//                        }
                        }
                    });
                }
            }catch (Exception e){
                throw new ServiceException(e.getMessage(),e);
            }
        });
        return methodInvocation.proceed();
    }
}
